#pragma once
#include <iostream>
#include <pthread.h>
#include <functional>
#include "Sock.hpp"
#include "Protocal.hpp"
namespace vic
{
    using namespace vic_protocol;
    using func_t = std::function<Response(const Request &)>;
    class TcpServer;

    class ThreadData
    {
    public:
        ThreadData(int s, std::string ip, uint16_t port, TcpServer *p)
            : _sock(s), _ip(ip), _port(port), _tsvrp(p) {}
        ~ThreadData() {}
        int _sock;
        TcpServer *_tsvrp;
        std::string _ip;
        uint16_t _port;
    };

    class TcpServer
    {
    public:
        TcpServer(func_t func, uint16_t port) : _func(func), _port(port)
        {
        }
        ~TcpServer()
        {
        }
        void InitServer()
        {
            // 1.初始化
            _listensock.Socket();
            _listensock.Bind(_port);
            _listensock.Listen();
            logMessage(Info, "init server done,listensock:%d", _listensock.Fd());
        }
        static void *ThreadRoutine(void *args)
        {
            pthread_detach(pthread_self());
            ThreadData *td = static_cast<ThreadData *>(args);
            // std:: cout<<"running"<<std::endl;
            td->_tsvrp->ServiceIO(td->_sock, td->_ip, td->_port);

            delete td;
            return nullptr;
        }
        void ServiceIO(int sock, const std::string &ip, const uint16_t &port)
        {
            std::string inbuffer;
            while (true)
            {
                // 1.read/recv 保证用户获取一个准确的报文
                // 一直循环读取，边读边检测
                
                std::string package;
                int n = ReadPackage(sock, inbuffer, &package);
                if (n == -1)
                    break;
                else if (n == 0)
                    continue;
                else
                {

                    package = RemoveHeader(package,n);

                    
                    Request req;
                    req.DeSerialize(package); // 反序列化
                    // 3.提取用户请求的数据
                    Response resp = _func(req);
                    // 4.给用户反回向应
                    // 序列化 形成可发送数据
                    std::string send_string;
                    resp.Serialize(&send_string);
                    //5.添加报头
                    send_string=AddHeader(send_string);
                    // 6.发送到网络
                    send(sock,send_string.c_str(),send_string.size(),0);
                }
            }
        }

        void Start()
        {
            for (;;)
            {
                std::string clientip;
                uint16_t clientport;
                int sock = _listensock.Accept(&clientip, &clientport);
                if (sock < 0)
                    continue;
                logMessage(Debug, "get a new client info:[%s:%d]", clientip.c_str(), clientport);

                pthread_t tid;
                ThreadData *td = new ThreadData(sock, clientip, clientport, this);
                pthread_create(&tid, nullptr, ThreadRoutine, td);
            }
        }

    private:
        uint16_t _port;
        Sock _listensock;
        func_t _func;
    };
}